﻿using Inovout.Kuajing.Lottery.Models;
using Inovout.Kuajing.Lottery.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Inovout.Kuajing.Lottery.Services
{
    public class LotteryService
    {
        public static HashSet<ActiveUserClickInfo> userClick = new HashSet<ActiveUserClickInfo>();
        public static List<ActiveRedPacketInfo> activePackets = new List<ActiveRedPacketInfo>();
        private static readonly object clickLocker = new object();
        private static readonly object packetLocker = new object();
        private RedPacketRepository redPacketRepository;
        public LotteryService()
        {
            redPacketRepository = new RedPacketRepository();
        }

        static LotteryService()
        {
            InitUserClick();
            InitRedPacket();
        }

        private static void InitRedPacket()
        {
            IRedPacketService redPacketService = ComponentRegistry.Resolve<RedPacketService>();
            IActiveService activeService = ComponentRegistry.Resolve<ActiveService>();
            IEnumerable<Active> actives = activeService.FindValikActives();
            if (actives != null && actives.Count() > 0)
            {
                foreach (Active active in actives)
                {
                    ActiveRedPacketInfo activePacketInfo = new ActiveRedPacketInfo();
                    activePacketInfo.Active = active;
                    IEnumerable<RedPacket> enumerRedPackets = redPacketService.FindRedPacketByActive(active);
                    foreach (RedPacket redPacket in enumerRedPackets)
                    {
                        activePacketInfo.RedPackets.Add(redPacket);
                    }
                    activePackets.Add(activePacketInfo);
                }
            }
        }


        private static void InitUserClick()
        {
            IClickService clickService = ComponentRegistry.Resolve<ClickService>();
            IActiveService activeService = ComponentRegistry.Resolve<ActiveService>();
            IEnumerable<Active> actives = activeService.FindValikActives();
            if (actives != null && actives.Count() > 0)
            {
                foreach (Active active in actives)
                {
                    ActiveUserClickInfo activeUserClickInfo = new ActiveUserClickInfo();
                    activeUserClickInfo.Active = active;
                    IEnumerable<Click> enumerClicks = clickService.FindClickByActive(active);

                    foreach (Click clickinfo in enumerClicks)
                    {
                        activeUserClickInfo.UserClick.Add(clickinfo.UserCode, clickinfo.ClickCount);
                    }
                    userClick.Add(activeUserClickInfo);
                }
            }
        }


        /// <summary>
        /// 更新用户的点击数目
        /// </summary>
        /// <param name="userCode"></param>
        /// <param name="active"></param>
        /// <returns></returns>
        public bool UpdateUserClick(string userCode, Active active, out bool is_NewUser)
        {
            is_NewUser = false;
            lock (clickLocker)
            {
                var tempUserClick = userClick.Where(n => n.Active.Id == active.Id);
                if (tempUserClick != null && tempUserClick.Count() > 0)
                {
                    ActiveUserClickInfo activeUserClickInfo = tempUserClick.First();
                    if (activeUserClickInfo.UserClick.Keys.Contains(userCode))
                    {
                        var data = activeUserClickInfo.UserClick.Where(n => n.Key == userCode).First();
                        if (data.Value < active.ClickCount)
                        {
                            KeyValuePair<string, int> click = new KeyValuePair<string, int>(userCode, data.Value + 1);
                            userClick.Where(n => n.Active.Id == active.Id).First().UserClick.Remove(userCode);
                            userClick.Where(n => n.Active.Id == active.Id).First().UserClick.Add(userCode, data.Value + 1);
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    else
                    {
                        userClick.Where(n => n.Active.Id == active.Id).First().UserClick.Add(userCode, 1);
                        is_NewUser = true;
                        return true;
                    }
                }
                else
                {
                    return false;
                }
            }
        }


        /// <summary>
        /// 获取红包
        /// </summary>
        /// <param name="userCode"></param>
        /// <param name="active"></param>
        /// <returns></returns>
        public bool GetRedPacket(string userCode, Active active, out RedPacket prize, bool is_NewUser)
        {
            prize = new RedPacket();
            lock (packetLocker)
            {
                var packets = activePackets.Where(n => n.Active.Id == active.Id);
                if (packets != null && packets.Count() > 0 && packets.First().RedPackets.Count() > 0)
                {
                    ActiveRedPacketInfo activeRedPacketInfo = packets.First();
                    RedPacket redPacket = activeRedPacketInfo.RedPackets[new Random().Next(activeRedPacketInfo.redPackets.Count())];
                    //更新红包的状态和用户的点击数
                    //redPacketRepository.UpdateRedPacket(redPacket, active, userCode, is_NewUser);
                    redPacketRepository.UpdateRedPacket(redPacket, active);
                    activePackets.Where(n => n.Active.Id == active.Id).First().RedPackets.Remove(redPacket);
                    prize = redPacket;
                    return true;
                }
                else
                {
                    //更新活动已结束
                    redPacketRepository.UpdateActive(active);
                    return false;
                }
            }


        }


        public void SaveWinnersList(string userCode, RedPacket redPacket)
        {
            WinnersList winnersList = new WinnersList();
            winnersList.RedPacket = redPacket;
            winnersList.UserCode = userCode;
            redPacketRepository.SaveWinnersList(winnersList);
        }

    }
}
